/**
 * 
 */
package Utils;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Image;
import java.awt.Insets;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.net.URL;
import java.util.NoSuchElementException;
import java.util.Random;
import java.util.Scanner;

import javax.swing.ImageIcon;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

import GUI.CustomDialog;
import java.awt.Component;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.image.BufferedImage;
import java.util.Timer;
import java.util.TimerTask;
import javax.swing.Icon;
/**
 * @author Avia Tam
 * @author Assaf Miron
 *
 */
public abstract class Utils {

	/**
	 * This Function Creates an Array of Doubles
	 * @param doubles Number of Double Variable
	 * @return An Array of the Inputed Doubles
	 */
	public static Double[] createDoubleArray(Double...doubles)
	{
		// Create a Return Variable in the Length of the Input Variables
		Double[] ret = new Double[doubles.length];
		// Create an Index for the Array
		int j = 0;
		// For Each Parameter in the Input Array Add to the Return Array
		for(Double i : doubles)
		{
			// Add the i Double Parameter to the Return Array
			ret[j] = i;
			// Increment the Index
			j++;
		}
		// Return the Newly created Double Array
		return ret;
	}

	/**
	 * This is a Helper function for displaying a question to the Player and returning its answer
	 * @param diagQuestion The Question to Display to the Player
	 * @return The Players' Answer (Yes - True, No - False)
	 */
	public static Boolean showPlayerDialog(String diagQuestion)
	{

		Boolean ans = false;
		// Show a Confirm Dialog and Get the User Answer
		int userResponse = JOptionPane.showConfirmDialog(
				null,
				diagQuestion,
				"Java Monopoly Question",
				JOptionPane.YES_NO_OPTION,
				JOptionPane.QUESTION_MESSAGE);

		// Check the Answer
		switch (userResponse)
		{
		case JOptionPane.YES_OPTION:
			ans = true;
			break;
		case JOptionPane.NO_OPTION:
			ans = false;
			break;
		}
		// Return the correct value
		return ans;
	}

	/**
	 * Show a User Error Dialog
	 * @param parent The Parent Component for the Dialog
	 * @param message The Message to display
	 */
	public static void showError(Component parent, String message){
	    JOptionPane.showMessageDialog(parent, message, "Monopoly Game Error", JOptionPane.ERROR_MESSAGE);
	}

	/**
	 * Prints a Formated Message to the Screen
	 * @param message The Text you want to Print
	 */
	public static void writeText(String... message)
	{
		String strMessage = "";
		// For Each String in the Messages String Array
		for(String i : message)
		{
			// Print the String to the Screen
			strMessage += (i + " ");
		}

		// Show the Message
		CustomDialog customDialog = new CustomDialog(strMessage);
		// Show The Dialog and Start the Countdown
		customDialog.start();
	}

	/**
	 * This Function Reads a String Input from the User
	 * @param message A Message to display to the User, Explaining the input
	 * @param showMessage Show the Message?
	 * @return The User Input
	 */
	public static String readText(String message, boolean showMessage)
	{
		try
		{
			// Create a Scanner object to read the User input
			Scanner scanner = new Scanner(System.in);
			// Check if to Show the Input Message
			if(showMessage)
			{
				// Print the Message
				System.out.print(message + " ");
			}
			// Return the User Input
			return scanner.nextLine();
		}
		catch(NoSuchElementException e)
		{
			// No Line was read
			return "";
		}
	}

	/**
	 * Creates a Random Color
	 * @return A Random Color from the Colors Palette
	 */
	public static Color getRandomColor()
	{
		Color retColor;
		// Create a Random Number Generator
		Random generator = new Random();
		// Create a Random Color from a:
		// 	Random Red Color (A Number between 0-255) 
		// 	Random Green Color (A Number between 0-255)
		// 	Random Blue Color (A Number between 0-255)
		retColor = new Color(generator.nextInt(255),generator.nextInt(255),generator.nextInt(255));
		// Return the Random Generated Color
		return retColor;
	}

	/**
	 * Sets the Look and Feel of the Windows
	 */
	public static void setLookAndFeel()
	{
		try 
		{
			// Set System L&F
			UIManager.setLookAndFeel(
					UIManager.getSystemLookAndFeelClassName());
		} 
		catch (UnsupportedLookAndFeelException e) {
			// handle exception
			e.printStackTrace();
		}
		catch (ClassNotFoundException e) {
			// handle exception
			e.printStackTrace();
		}
		catch (InstantiationException e) {
			// handle exception
			e.printStackTrace();
		}
		catch (IllegalAccessException e) {
			// handle exception
			e.printStackTrace();
		}
	}

	/**
	 * Returns an Image from an Image Path
	 * By Liron Blecher
	 * @param name The Image Path
	 * @return An Image Object
	 */
	public static Image getImage (String name) {
		// Check that the Path is not Empty
		if (name == null || name.isEmpty()) {
			return null;
		}
		// Get the URL for the Image
		URL imageURL = Toolkit.class.getResource(name);
		// Check that the URL is Not Empty
		if (imageURL == null) {
			return null;
		}
		// Return an Image Object from the Image URL
		return Toolkit.getDefaultToolkit().createImage(imageURL);
	}

	/**
	 * Creates an New Image Icon from a Image Path
	 * By Liron Blecher
	 * @param name The Image Path
	 * @return An Image Icon
	 */
	public static ImageIcon getImageIcon (String name) {
		Icon missing = new MissingIcon();
		// Get the Image
		Image image = getImage("/images/" + name);
		// Check that Image is Not Empty
		if (image == null) {
			return new ImageIcon(iconToImage(missing));
		}
		// Return the Image Icon Object
		return new ImageIcon(image);
	}

	/**
	 * Converts an {@link Icon} to an {@link  ImageIcon}
	 * taken from http://groups.google.com/group/comp.lang.java.programmer/browse_thread/thread/388fc875e6cf2faf/d94b5f2241e0463f?lnk=raot&pli=1
	 * @param icon The Icon to Convert
	 * @return An Image Icon of that Icon
	 */
	private static Image iconToImage(Icon icon) {
          if (icon instanceof ImageIcon) {
              return ((ImageIcon)icon).getImage();
          } else {
              int w = icon.getIconWidth();
              int h = icon.getIconHeight();
              GraphicsEnvironment ge =  GraphicsEnvironment.getLocalGraphicsEnvironment();
              GraphicsDevice gd = ge.getDefaultScreenDevice();
              GraphicsConfiguration gc = gd.getDefaultConfiguration();
              BufferedImage image = gc.createCompatibleImage(w, h);
              Graphics2D g = image.createGraphics();
              icon.paintIcon(null, g, 0, 0);
              g.dispose();
              return image;
          }
      }

	/**
	 * Scale an image
	 * @param icon image icon  to scale
	 * @param width new width
	 * @param height new width
	 * @return the newly scaled image
	 */
	public static ImageIcon createScaledIcon(String imagePath, int width, int	height, Insets insets ) 
	{
		ImageIcon icon = getImageIcon(imagePath);
		try {

			int w, h;
			if(insets != null)
			{
				// Get the Height and Width with out the Parent Insets
				w = width - insets.left - insets.right;
				h = height - insets.top - insets.bottom;
			}
			else
			{
				w = width;
				h = height;
			}
			// Get the Image Original Height and Width
			int src_w = icon.getImage().getWidth(null);
			int src_h = icon.getImage().getHeight(null);
			// Calculate the new Scaled X and Y Position
			double scale_x = ((double)w)/src_w;
			double scale_y = ((double)h)/src_h;
			// Get the Minimum Scale
			double scale = Math.min(scale_x, scale_y);
			// Calculate the New Height and Width
			int dst_w = (int)(scale * src_w);
			int dst_h = (int)(scale * src_h);

			// Maximum Image size can be the Original Size
			if((dst_w > src_w) || (dst_h > src_h))
				// Return the Original Image Size
				return new ImageIcon(icon.getImage().getScaledInstance(src_w, src_h, Image.SCALE_SMOOTH));
			else
				// Return the new Size
				return new ImageIcon( icon.getImage().getScaledInstance(dst_w, dst_h, Image.SCALE_SMOOTH ));
		}
		catch(Exception e) {
			//may have used unsuitable width/height, just return the original
			return icon;
		}
	}

	/**
	 * Converts a String to HTML
	 * @param string The String to Convert
	 * @return The Converted String as HTML
	 */
	public static String StringToHTML(String string){
		String res;
		// Convert all New Lines to HTML Break Lines
		res = string.replaceAll("\n","<BR>");
		// Add the Prefix and Suffix of the HTML Tag
		res="<HTML>" + res + "</HTML>";
		// Return the Converted String
		return res;
	}

	/**
	 * Get the Center of the Screen Position
	 * @param width The Object Width
	 * @param height The Object Height
	 * @return A Rectangle of Center Screen Position
	 */
	public static Rectangle posCenterScreen(Integer width, Integer height)
	{
		Rectangle rec = new Rectangle();
		// Get the Screen Size
		Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
		// Set X Position in Center Screen
		int x = (screen.width - width) / 2;
		// Set YPosition in Center Screen
		int y = (screen.height - height) / 2;
		// Set the Bounds of the Rectangle
		rec.setBounds(x, y, width, height);

		return rec;
	}

	/**
	 * Create a New Panel with an Image
	 * @param imagePath The Image Path you want to Add
	 * @return A Panel with an Image
	 */
	public static JPanel CreateImagePanel(String imagePath, String label) {
		JPanel pnlPicture = new JPanel();
		ImageIcon image = getImageIcon(imagePath);
		if(image != null)
		{
			JLabel lblImage = new JLabel(createScaledIcon(imagePath, image.getIconWidth(), image.getIconHeight(),null));
			lblImage.setToolTipText(label);
			pnlPicture.add(lblImage);
		}
		pnlPicture.setOpaque(false);
		return pnlPicture;
	}

	/**
	 * Create a New Panel with an Image
	 * @param imagePath The Image Path you want to Add
	 * @return A Panel with an Image
	 */
	public static JPanel CreateImagePanel(ImageIcon image, String label) {
		JPanel pnlPicture = new JPanel();
		JLabel lblImage = new JLabel(image);
		// Verify that the Text is not Empty
		if( (label != null) && (!label.isEmpty()) )
			lblImage.setToolTipText(label);
		// Add The Image to the Panel
		pnlPicture.add(lblImage);
		// Make Transparent
		pnlPicture.setOpaque(false);
		return pnlPicture;
	}

	/**
	 * Repaints and Validates the Component and all his Components
	 * @param component The Component that you want to Repaint and Validate
	 */
	public static void repaintAndValidateAll(JComponent component)
	{
		try
		{
			// Check that Component has Children
			if(component.getComponentCount() > 0)
			{
				// Repaint and Validate all the Components' Components
				for(int i = 0; i < component.getComponentCount(); i++)
				{
					component.getComponent(i).validate();
					component.getComponent(i).repaint();
				}
			}
		}
		catch(Exception e)
		{ ; }

		// Repaint and Validate the Component itself
		component.repaint();
		component.validate();
	}
}
